﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.IO.Compression;
using MacomberMap.Common.Database_Interface.CIM.Components;

namespace MacomberMap.Common.Database_Interface.CIM.CIM_Interface
{
    /// <summary>
    /// This class is responsible for writing out a CIM index file.
    /// </summary>
    public static class CIM_Index_Writer
    {
        /// <summary>
        /// Write out a CIM index file
        /// </summary>
        /// <param name="FileName"></param>
        public static void WriteIndex(String FileName)
        {
            using (FileStream fS = new FileStream(FileName, FileMode.Create, FileAccess.Write))
            {
                byte[] OutHeader = Encoding.UTF8.GetBytes(" MM Server System, (C) 2009 ERCOT, Michael E. Legatt, Ph.D.\n");
                fS.Write(OutHeader,0, OutHeader.Length);
                using (GZipStream gS = new GZipStream(fS, CompressionMode.Compress))
                using (StreamWriter sW = new StreamWriter(gS, Encoding.UTF8))
                {
                    //Write our maximum mRID
                    sW.WriteLine("Maximum mRID:" + MM_Database_CIM.MaxMRID.ToString());
                    

                    //Write our attributes out
                    sW.WriteLine("Attributes:{0}", MM_Database_CIM.Attributes.Count);
                    foreach (String Attr in MM_Database_CIM.Attributes.Keys)
                        sW.WriteLine(Attr);

                    //Write our types out
                    sW.WriteLine("Types:{0}", MM_Database_CIM.Types.Count);
                    foreach (KeyValuePair<String, int> CIMType in MM_Database_CIM.Types)
                    {
                        sW.Write(CIMType.Key + ",");
                        foreach (int AttrOut in MM_Database_CIM.AttributesByType[(byte)CIMType.Value])
                            sW.Write(AttrOut.ToString() + ",");
                        sW.WriteLine();
                    }

                    //Write our type-to-type mappings
                    sW.WriteLine("TypeToTypes:{0}", MM_Database_CIM.TypeToTypes.Count);
                    foreach (KeyValuePair<byte, List<byte>> kvp in MM_Database_CIM.TypeToTypes)
                    {
                        sW.Write(kvp.Key.ToString());
                        foreach (byte kvp2 in kvp.Value)
                            sW.Write("," + kvp2.ToString());                        
                        sW.WriteLine();
                    }

                    sW.WriteLine("TypeFromTypes:{0}", MM_Database_CIM.TypeFromTypes.Count);
                    foreach (KeyValuePair<byte, List<byte>> kvp in MM_Database_CIM.TypeFromTypes)
                    {
                        sW.Write(kvp.Key.ToString());
                        foreach (byte kvp2 in kvp.Value)
                            sW.Write("," + kvp2.ToString());
                        sW.WriteLine();
                    }


                    //Write our elements
                    sW.WriteLine("Elements:{0}", MM_Database_CIM.Elements.Count);
                    foreach (CIM_Element Elem in MM_Database_CIM.Elements.Values)
                    {
                        sW.Write("{0},{1},{2},{3},", Elem.rdfID.ToString(), Elem.Type, Elem.Start, Elem.Length);
                        for (int a = 0; a < Elem._InLinks.Count; a++)
                            sW.Write(a == 0 ? Elem._InLinks[a].ToString() : "|" + Elem._InLinks[a].ToString());
                        sW.Write(",");
                        for (int a = 0; a < Elem._OutLinks.Count; a++)
                            sW.Write(a == 0 ? Elem._OutLinks[a].ToString() : "|" + Elem._OutLinks[a].ToString());
                        sW.Write(",");
                        sW.Write(Convert.ToBase64String(Elem.CheckSum));
                        sW.WriteLine();
                    }

                    //Write our TEIDs
                    sW.WriteLine("TEIDs:{0}", MM_Database_CIM.TEIDs.Count);
                    foreach (KeyValuePair<UInt64, CIM_Element> kvp in MM_Database_CIM.TEIDs)
                        sW.WriteLine("{0},{1}", kvp.Key, kvp.Value.rdfID);

                    sW.Flush();                    
                }
            }
        }
    }
}
